package com.lennon.spring.cloud.ms.invoke;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.EurekaClient;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication
public class InvokeApp {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(InvokeApp.class, args);
    }
}


@RestController
class InvokeController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private EurekaClient eurekaClient;

    @Autowired
    private InvokeFeignClient feignClient;


    @GetMapping("/invoke/user/{id}")
    public User getUser(@PathVariable Long id) {
        User user = restTemplate.getForObject("http://microservice-user/user/{id}", User.class, id);
        return user;
    }

    @GetMapping("/invoke/user2/{id}")
    public User getUser2(@PathVariable Long id) {
        return feignClient.getUser(id);
    }

    @GetMapping("/invoke/post")
    public User postUser(User user) {
        System.out.println(user);
        return feignClient.postUser(user);
    }

    @GetMapping("/invoke/get")
    public User postUserGet(User user) {

        return feignClient.postUserGet(user);
    }

    @GetMapping("/server")
    public InstanceInfo serverName() {
        InstanceInfo nextServerFromEureka = eurekaClient.getNextServerFromEureka("MICROSERVICE-USER", false);
        return nextServerFromEureka;
    }
}


@FeignClient("microservice-user")
interface InvokeFeignClient {

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    User getUser(@PathVariable("id") Long id);

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    User postUser(@RequestBody User user);

    // Feign不支持复杂对象的get请求
    @RequestMapping(value = "/user-get", method = RequestMethod.GET)
    User postUserGet(User user);
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class User {

    private long id;

    private int age;

    private String username;

    private String name;

    private double balance;
}
